bitkeeper revision 1.1051 (40ed377bW0cMKaeeMSXfQOknw3iMaw)
authormjw@wray-m-3.hpl.hp.com <mjw@wray-m-3.hpl.hp.com>
Thu, 8 Jul 2004 12:00:59 +0000 (12:00 +0000)
committermjw@wray-m-3.hpl.hp.com <mjw@wray-m-3.hpl.hp.com>
Thu, 8 Jul 2004 12:00:59 +0000 (12:00 +0000)
Documentation.

tools/python/xen/xend/server/blkif.py
tools/python/xen/xend/server/channel.py
tools/python/xen/xend/server/controller.py

index 5596ddb842ba2b300c486850dae541c747e8d407..bf51640ee19f4319566a91e052ca5b92b5db0833 100755 (executable)
@@ -29,8 +29,12 @@ class BlkifControllerFactory(controller.ControllerFactory):
     def createInstance(self, dom, recreate=0):
         """Create a block device controller for a domain.
 
-        dom      domain
-        recreate if true it's a recreate (after xend restart)
+        @param dom: domain
+        @type  dom: int
+        @param recreate: if true it's a recreate (after xend restart)
+        @type  recreate: bool
+        @return: deferred
+        @rtype: twisted.internet.defer.Deferred
         """
         d = defer.Deferred()
         blkif = self.getInstanceByDom(dom)
@@ -51,9 +55,10 @@ class BlkifControllerFactory(controller.ControllerFactory):
     def getDomainDevices(self, dom):
         """Get the block devices for a domain.
 
-        dom domain
-
-        returns devices
+        @param dom: domain
+        @type  dom: int
+        @return: devices
+        @rtype:  [device]
         """
         blkif = self.getInstanceByDom(dom)
         return (blkif and blkif.getDevices()) or []
@@ -61,10 +66,12 @@ class BlkifControllerFactory(controller.ControllerFactory):
     def getDomainDevice(self, dom, vdev):
         """Get a block device from a domain.
 
-        dom  domain
-        vdev device index
-
-        returns device
+        @param dom: domain
+        @type  dom: int
+        @param vdev: device index
+        @type  vedv: int
+        @return: device
+        @rtype:  device
         """
         blkif = self.getInstanceByDom(dom)
         return (blkif and blkif.getDevice(vdev)) or None
@@ -72,8 +79,10 @@ class BlkifControllerFactory(controller.ControllerFactory):
     def setControlDomain(self, dom, recreate=0):
         """Set the back-end block device controller domain.
 
-        dom      domain
-        recreate if true it's a recreate (after xend restart)
+        @param dom: domain
+        @type  dom: int
+        @param recreate: if true it's a recreate (after xend restart)
+        @type  recreate: int
         """
         if self.dom == dom: return
         self.deregisterChannel()
@@ -84,14 +93,19 @@ class BlkifControllerFactory(controller.ControllerFactory):
 
     def getControlDomain(self):
         """Get the back-end block device controller domain.
+
+        @return: domain
+        @rtype:  int
         """
         return self.dom
 
     def reattachDevice(self, dom, vdev):
         """Reattach a device (on changing control domain).
 
-        dom  domain
-        vdev device index
+        @param dom: domain
+        @type  dom: int
+        @param vdev: device index
+        @type  vdev: int
         """
         blkif = self.getInstanceByDom(dom)
         if blkif:
@@ -102,6 +116,9 @@ class BlkifControllerFactory(controller.ControllerFactory):
 
     def devicesAttached(self):
         """Check if all devices are attached.
+
+        @return: true if all devices attached
+        @rtype:  bool
         """
         attached = 1
         for blkif in self.getInstances():
@@ -111,19 +128,32 @@ class BlkifControllerFactory(controller.ControllerFactory):
         return attached
                          
     def reattached(self):
-        """Notify all block interface we have been reattached
+        """Notify all block interfaces we have been reattached
         (after changing control domain).
         """
         for blkif in self.getInstances():
             blkif.reattached()
 
     def respond_be_create(self, msg, d):
+        """Response handler for a be_create message.
+        Calls I{d} with the block interface created.
+
+        @param msg: message
+        @type  msg: xu message
+        @param d: deferred to call
+        @type  d: Deferred
+        """
         print 'respond_be_create>'
         val = unpackMsg('blkif_be_create_t', msg)
         blkif = self.getInstanceByDom(val['domid'])
         d.callback(blkif)
     
     def respond_be_connect(self, msg):
+        """Response handler for a be_connect message.
+
+        @param msg: message
+        @type  msg: xu message
+        """
         print 'respond_be_connect>', self
         val = unpackMsg('blkif_be_connect_t', msg)
         blkif = self.getInstanceByDom(val['domid'])
@@ -133,6 +163,15 @@ class BlkifControllerFactory(controller.ControllerFactory):
             pass
     
     def respond_be_vbd_create(self, msg, d):
+        """Response handler for a be_vbd_create message.
+        Tries to grow the vbd, and passes the deferred I{d} on for
+        the grow to call.
+
+        @param msg: message
+        @type  msg: xu message
+        @param d: deferred to call
+        @type  d: Deferred
+        """
         print 'recv_be_vbd_create>', self
         val = unpackMsg('blkif_be_vbd_create_t', msg)
         blkif = self.getInstanceByDom(val['domid'])
@@ -145,6 +184,13 @@ class BlkifControllerFactory(controller.ControllerFactory):
             pass
     
     def respond_be_vbd_grow(self, msg, d):
+        """Response handler for a be_vbd_grow message.
+
+        @param msg: message
+        @type  msg: xu message
+        @param d: deferred to call
+        @type  d: Deferred or None
+        """
         print 'recv_be_vbd_grow>', self
         val = unpackMsg('blkif_be_vbd_grow_t', msg)
         # Check status?
@@ -155,6 +201,13 @@ class BlkifControllerFactory(controller.ControllerFactory):
             self.reattachDevice(val['domid'], val['vdevice'])
 
     def recv_be_driver_status_changed(self, msg, req):
+        """Request handler for be_driver_status_changed messages.
+        
+        @param msg: message
+        @type  msg: xu message
+        @param req: request flag (true if the msg is a request)
+        @type  req: bool
+        """
         print 'recv_be_driver_status_changed>', self, req
         val = unpackMsg('blkif_be_driver_status_changed_t', msg)
         status = val['status']
@@ -222,6 +275,17 @@ class BlkifController(controller.Controller):
         return self.devices.get(vdev)
 
     def addDevice(self, vdev, mode, segment):
+        """Add a device to the device table.
+
+        @param vdev:     device index
+        @type  vdev:     int
+        @param mode:     read/write mode
+        @type  mode:     string
+        @param segment:  segment
+        @type  segment:  int
+        @return: device
+        @rtype:  BlkDev
+        """
         if vdev in self.devices: return None
         dev = BlkDev(self, vdev, mode, segment)
         self.devices[vdev] = dev
@@ -230,12 +294,16 @@ class BlkifController(controller.Controller):
     def attachDevice(self, vdev, mode, segment, recreate=0):
         """Attach a device to the specified interface.
 
-        vdev     device index
-        mode     read/write mode
-        segment  segment
-        recreate if true it's being recreated (after xend restart)
-
-        returns deferred
+        @param vdev:     device index
+        @type  vdev:     int
+        @param mode:     read/write mode
+        @type  mode:     string
+        @param segment:  segment
+        @type  segment:  int
+        @param recreate: if true it's being recreated (after xend restart)
+        @type  recreate: bool
+        @return: deferred
+        @rtype:  Deferred
         """
         dev = self.addDevice(vdev, mode, segment)
         if not dev: return -1
index caaa66e28c744333c1d0e39fe278f4a9f2b53d59..d78ba252cb782caab70b6469ed31c15a4d3354db 100755 (executable)
@@ -2,7 +2,7 @@
 
 import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
 from xen.lowlevel import xu
-from messages import msgTypeName
+from messages import msgTypeName, printMsg
 
 VIRQ_MISDIRECT  = 0  # Catch-all interrupt for unbound VIRQs.
 VIRQ_TIMER      = 1  # Timebase update, and/or requested timeout.
@@ -222,12 +222,18 @@ class Channel(BaseChannel):
 
     def getLocalPort(self):
         """Get the local port.
+
+        @return: local port
+        @rtype:  int
         """
         if self.closed: return -1
         return self.port.local_port
 
     def getRemotePort(self):
         """Get the remote port.
+
+        @return: remote port
+        @rtype:  int
         """
         if self.closed: return -1
         return self.port.remote_port
@@ -248,8 +254,9 @@ class Channel(BaseChannel):
     def registerDevice(self, types, dev):
         """Register a device controller.
 
-        @param types message types the controller handles
-        @param dev   device controller
+        @param types: message types the controller handles
+        @type  types: array of ints
+        @param dev:   device controller
         """
         if self.closed: return
         self.devs.append(dev)
@@ -259,7 +266,7 @@ class Channel(BaseChannel):
     def deregisterDevice(self, dev):
         """Remove the registration for a device controller.
 
-        @param dev device controller
+        @param dev: device controller
         """
         if dev in self.devs:
             self.devs.remove(dev)
@@ -270,13 +277,20 @@ class Channel(BaseChannel):
     def getDevice(self, type):
         """Get the device controller handling a message type.
 
-        @param type message type
-        @returns controller or None
+        @param type: message type
+        @type  type: int
+        @return: controller or None
+        @rtype:  device controller
         """
         return self.devs_by_type.get(type)
 
     def getMessageType(self, msg):
         """Get a 2-tuple of the message type and subtype.
+
+        @param msg: message
+        @type  msg: xu message
+        @return: type info
+        @rtype:  (int, int)
         """
         hdr = msg.get_header()
         return (hdr['type'], hdr.get('subtype'))
index 6d0bd9295fa4e7ad287424b7ec4045f8d1d041ee..a9f416908a0d601a5aed0023cc61a8b148f763de 100755 (executable)
@@ -1,53 +1,80 @@
 # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
+"""General support for controllers, which handle devices
+for a domain.
+"""
 
 from twisted.internet import defer
 defer.Deferred.debug = 1
 
 import channel
-from messages import msgTypeName
+from messages import msgTypeName, printMsg
 
-DEBUG=0
+DEBUG = 0
 
 class OutOfOrderError(RuntimeError):
-    """Error reported when a response arrives out of order.
+    """Error reported when a response message arrives out of order.
     """
     pass
 
 class Responder:
-    """Handler for a response to a message.
+    """Handler for a response to a message with a specified id.
     """
 
     def __init__(self, mid, deferred):
         """Create a responder.
 
-        mid      message id of response to handle
-        deferred deferred object holding the callbacks
+        @param mid: message id of response to handle
+        @type  mid: int
+        @param deferred: deferred object holding the callbacks
+        @type  deferred: Deferred
         """
         self.mid = mid
         self.deferred = deferred
 
     def responseReceived(self, msg):
+        """Entry point called when a response message with the right id arrives.
+        Calls callback on I{self.deferred} with the message.
+
+        @param msg: response message
+        @type  msg: xu message
+        """
         if self.deferred.called: return
         self.deferred.callback(msg)
 
     def error(self, err):
+        """Entry point called when there has been an error.
+        Calls errback on I{self.deferred} with the error.
+
+        @param err: error
+        @type  err: Exception
+        """
         if self.deferred.called: return
         self.deferred.errback(err)
 
 class CtrlMsgRcvr:
     """Abstract class for things that deal with a control interface to a domain.
-
-    Instance variables:
-
-    dom       : the domain we are a control interface for
-    majorTypes: list of major message types we are interested in
-    subTypes  : mapping of message subtypes to methods
+    Once I{registerChannel} has been called, our message types are registered
+    with the channel to the domain. The channel will call I{requestReceived}
+    when a request arrives, or I{responseReceived} when a response arrives,
+    if they have one of our message types.
+
+    @ivar dom: the domain we are a control interface for
+    @type dom: int
+    @ivar majorTypes: major message types we are interested in
+    @type majorTypes: [int]
+    @ivar subTypes: mapping of message subtypes to methods
+    @ivar subTypes: {int:method}
+    @ivar timeout: timeout (in seconds) for message handlers
+    @type timeout: int
     
-    channel   : channel to the domain
-    idx       : channel index
+    @ivar channel: channel to the domain
+    @type channel: Channel
+    @ivar idx: channel index
+    @ivar idx: string
+    @ivar responders: table of message response handlers
+    @type responders: {int:Responder}
     """
 
-
     def __init__(self):
         self.channelFactory = channel.channelFactory()
         self.majorTypes = [ ]
@@ -56,22 +83,25 @@ class CtrlMsgRcvr:
         self.channel = None
         self.idx = None
         self.responders = []
-        # Timeout (in seconds) for deferreds.
         self.timeout = 10
 
     def setTimeout(self, timeout):
         self.timeout = timeout
 
     def requestReceived(self, msg, type, subtype):
-        """Dispatch a request to handlers.
-
-        msg     message
-        type    major message type
-        subtype minor message type
+        """Dispatch a request message to handlers.
+        Called by the channel for requests with one of our types.
+
+        @param msg:     message
+        @type  msg:     xu message
+        @param type:    major message type
+        @type  type:    int
+        @param subtype: minor message type
+        @type  subtype: int
         """
-        msgid = msg.get_header()['id']
         if DEBUG:
-            print 'requestReceived>', self, msgid, msgTypeName(type, subtype)
+            print 'requestReceived>',
+            printMsg(msg, all=1)
         method = self.subTypes.get(subtype)
         if method:
             method(msg, 1)
@@ -81,14 +111,23 @@ class CtrlMsgRcvr:
         
     def responseReceived(self, msg, type, subtype):
         """Dispatch a response to handlers.
-
-        msg     message
-        type    major message type
-        subtype minor message type
+        Called by the channel for responses with one of our types.
+        
+        First looks for a message responder for the message's id.
+        See L{callResponders}, L{addResponder}.
+        If there is no responder, looks for a message handler for
+        the message type/subtype.
+
+        @param msg:     message
+        @type  msg:     xu message
+        @param type:    major message type
+        @type  type:    int
+        @param subtype: minor message type
+        @type  subtype: int
         """
-        msgid = msg.get_header()['id']
         if DEBUG:
-            print 'responseReceived>', self, msgid, msgTypeName(type, subtype)
+            print 'responseReceived>',
+            printMsg(msg, all=1)
         if self.callResponders(msg):
             return
         method = self.subTypes.get(subtype)
@@ -100,16 +139,21 @@ class CtrlMsgRcvr:
 
     def addResponder(self, mid, deferred):
         """Add a responder for a message id.
-        The deferred is called with callback(msg) when a response
-        with the given message id arrives. Responses are expected
+        The I{deferred} is called with callback(msg) when a response
+        with message id I{mid} arrives. Responses are expected
         to arrive in order of message id. When a response arrives,
         waiting responders for messages with lower id have errback
         called with an OutOfOrder error.
 
-        mid      message id of response expected
-        deferred a Deferred to handle the response
+        Responders have a timeout set and I{deferred} will error
+        on expiry.
 
-        returns Responder
+        @param mid:      message id of response expected
+        @type  mid:      int
+        @param deferred: handler for the response
+        @type  deferred: Deferred
+        @return: responder
+        @rtype:  Responder
         """
         if self.timeout > 0:
             deferred.setTimeout(self.timeout)
@@ -119,10 +163,13 @@ class CtrlMsgRcvr:
 
     def callResponders(self, msg):
         """Call any waiting responders for a response message.
+        Looks for a responder registered for the message's id.
+        See L{addResponder}.
 
-        msg     response message
-        
-        returns 1 if there was a responder for the message, 0 otherwise
+        @param msg: response message
+        @type  msg: xu message
+        @return: 1 if there was a responder for the message, 0 otherwise
+        @rtype : bool
         """
         hdr = msg.get_header()
         mid = hdr['id']
@@ -133,7 +180,7 @@ class CtrlMsgRcvr:
                 break
             self.responders.pop()
             if resp.mid < mid:
-                print 'handleResponse> Out of order:', resp.mid, mid
+                print 'callResponders> Out of order:', resp.mid, mid
                 resp.error(OutOfOrderError())
             else:
                 handled = 1
@@ -148,7 +195,8 @@ class CtrlMsgRcvr:
     
     def registerChannel(self):
         """Register interest in our major message types with the
-        channel to our domain.
+        channel to our domain. Once we have registered, the channel
+        will call requestReceived or responseReceived for our messages.
         """
         self.channel = self.channelFactory.domChannel(self.dom)
         self.idx = self.channel.getIndex()
@@ -157,7 +205,8 @@ class CtrlMsgRcvr:
         
     def deregisterChannel(self):
         """Deregister interest in our major message types with the
-        channel to our domain.
+        channel to our domain. After this the channel won't call
+        us any more.
         """
         if self.channel:
             self.channel.deregisterDevice(self)
@@ -166,18 +215,23 @@ class CtrlMsgRcvr:
     def produceRequests(self):
         """Produce any queued requests.
 
-        return number produced
+        @return: number produced
+        @rtype:  int
         """
         return 0
 
     def writeRequest(self, msg, response=None):
         """Write a request to the channel.
 
-        msg      message
-        response Deferred to handle the response (optional)
+        @param msg:      request message
+        @type  msg:      xu message
+        @param response: response handler
+        @type  response: Deferred
         """
         if self.channel:
-            if DEBUG: print 'CtrlMsgRcvr>writeRequest>', self, msg
+            if DEBUG:
+                print 'CtrlMsgRcvr>writeRequest>',
+                printMsg(msg, all=1)
             if response:
                 self.addResponder(msg.get_header()['id'], response)
             self.channel.writeRequest(msg)
@@ -185,29 +239,33 @@ class CtrlMsgRcvr:
             print 'CtrlMsgRcvr>writeRequest>', 'no channel!', self
 
     def writeResponse(self, msg):
-        """Write a response to the channel.
+        """Write a response to the channel. This acknowledges
+        a request message.
+
+        @param msg:      message
+        @type  msg:      xu message
         """
         if self.channel:
-            if DEBUG: print 'CtrlMsgRcvr>writeResponse>', self, msg
+            if DEBUG:
+                print 'CtrlMsgRcvr>writeResponse>',
+                printMsg(msg, all=0)
             self.channel.writeResponse(msg)
         else:
             print 'CtrlMsgRcvr>writeResponse>', 'no channel!', self
             
 class ControllerFactory(CtrlMsgRcvr):
-    """Abstract class for factories creating controllers.
+    """Abstract class for factories creating controllers for a domain.
     Maintains a table of instances.
 
-    Instance variables:
-
-    instances : mapping of index to controller instance
-    dlist     : list of deferreds
-    dom       : domain
+    @ivar instances: mapping of index to controller instance
+    @type instances: {int: Controller}
+    @ivar dom: domain
+    @type dom: int
     """
 
     def __init__(self):
         CtrlMsgRcvr.__init__(self)
         self.instances = {}
-        self.dlist = []
         self.dom = 0
         
     def addInstance(self, instance):
@@ -241,6 +299,11 @@ class ControllerFactory(CtrlMsgRcvr):
 
     def createInstance(self, dom, recreate=0):
         """Create an instance. Define in a subclass.
+
+        @param dom: domain
+        @type  dom: int
+        @param recreate: true if the instance is being recreated (after xend restart)
+        @type  recreate: int
         """
         raise NotImplementedError()